package com.android.powerbankpad;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Looper;

import com.android.powerbankpad.base.ManageActivity;
import com.android.powerbankpad.network.CustomOkHttpClient;
import com.bumptech.glide.Glide;
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader;
import com.bumptech.glide.load.model.GlideUrl;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.https.HttpsUtils;
import com.lzy.okgo.interceptor.HttpLoggingInterceptor;
import com.ws.universal.tools.ContextInit;
import com.ws.universal.tools.OrrorLog;
import com.ws.universal.tools.carsh.Cockroach;
import com.ws.universal.tools.carsh.FileWriteUtils;
import com.ws.universal.tools.carsh.DebugSafeModeUI;
import com.ws.universal.tools.carsh.ExceptionHandler;
import com.ws.universal.tools.network.HttpLogInterceptor;
import com.ws.universal.tools.utils.LogcatUtils;

import java.io.InputStream;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import me.jessyan.autosize.AutoSize;
import me.jessyan.autosize.AutoSizeConfig;
import me.jessyan.autosize.onAdaptListener;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import xyz.doikki.videoplayer.ijk.IjkPlayerFactory;
import xyz.doikki.videoplayer.player.VideoViewConfig;
import xyz.doikki.videoplayer.player.VideoViewManager;

public class BaseApplication extends Application {
    public static Context context;
    public boolean isNetWork = true;

    @Override
    public void onCreate() {
        super.onCreate();
        context = this;
        //各种初始化
        initializeManagers();
    }

    private void initializeManagers() {

        ContextInit.initial(context);
        //CacheUtils.setString(Constants.serial_number, "");
        LogcatUtils.setGlobalTag(context.getString(R.string.app_name));
        //LogcatUtils.setLogSwitch(BuildConfig.DEBUG);
        initAutoSize();
        ManageActivity.getInstance();
        initOkGo();
        videoView();
        initAppCarshListener();
        //LeakCanary.setConfig(new LeakCanary.Config());
        // Create your custom OkHttpClient
        Glide.get(this).getRegistry().replace(GlideUrl.class, InputStream.class,
                new OkHttpUrlLoader.Factory((Call.Factory) CustomOkHttpClient.getCustomOkHttpClient()));

    }


    private void videoView() {
        //播放器配置，注意：此为全局配置，按需开启
        VideoViewManager.setConfig(VideoViewConfig.newBuilder().setLogEnabled(com.ws.universal.tools.takephoto.multipleimageselect.BuildConfig.DEBUG)//是否打印日志
                .setPlayerFactory(IjkPlayerFactory.create())//自定义播放核心 IjkPlayerFactory
                //.setPlayerFactory(AndroidMediaPlayerFactory.create()) //不推荐使用，兼容性较差
                //.setPlayerFactory(ExoMediaPlayerFactory.create()) //自定义播放核心 ExoMediaPlayerFactory
                //.setRenderViewFactory(SurfaceRenderViewFactory.create())//设置自己的渲染view，内部默认TextureView实现
                //.setEnableOrientation(false)//是否监听设备方向来切换全屏/半屏， 默认不开启
                //.setEnableOrientation(false)//根据手机重力感应自动切换横竖屏，默认false
                //.setEnableAudioFocus(false)// 监听系统中其他播放器是否获取音频焦点，实现不与其他播放器同时播放的效果，默认true
                //.setAdaptCutout(true) // 适配刘海屏，默认true
                //.setPlayOnMobileNetwork(false)  // 移动网络下提示用户会产生流量费用，默认不提示， 如果要提示则设置成false并在控制器中监听STATE_START_ABORT状态，实现相关界面，具体可以参考PrepareView的实现
                //.setProgressManager(new ProgressManagerImpl()) // 进度管理器，继承ProgressManager，实现自己的管理逻辑
                .setEnableAudioFocus(true)//是否开启AudioFocus监听， 默认开启
                //.setScreenScaleType(VideoView.SCREEN_SCALE_16_9)//设置视频比例
                .build());
    }

    /**
     * 初始化 okGo
     */
    private void initOkGo() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        HttpLogInterceptor loggingInterceptor = new HttpLogInterceptor(context.getString(R.string.app_name));
        //log打印级别，决定了log显示的详细程度
        loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY);
        //log颜色级别，决定了log在控制台显示的颜色
        loggingInterceptor.setColorLevel(Level.INFO);
        builder.addInterceptor(loggingInterceptor);
        //全局的读取超时时间
        builder.readTimeout(60000, TimeUnit.MILLISECONDS);
        //全局的写入超时时间
        builder.writeTimeout(60000, TimeUnit.MILLISECONDS);
        //全局的连接超时时间
        builder.connectTimeout(60000, TimeUnit.MILLISECONDS);
        //方法一：信任所有证书,不安全有风险
        HttpsUtils.SSLParams sslParams1 = HttpsUtils.getSslSocketFactory();
        builder.sslSocketFactory(sslParams1.sSLSocketFactory, sslParams1.trustManager);
        //OkHttpClient okHttpClient = SSLSocketClient.getUnsafeOkHttpClient();

        //必须调用初始化
        OkGo.getInstance().init(this)
                //忽略证书
                //.setOkHttpClient(okHttpClient)
                //建议设置OkHttpClient，不设置将使用默认的
                .setOkHttpClient(builder.build())
                //全局统一缓存模式，默认不使用缓存，可以不传
                //.setCacheMode(CacheMode.NO_CACHE)
                //全局统一缓存时间，默认永不过期，可以不传
                //.setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE)
                //全局统一超时重连次数，默认为三次，那么最差的情况会请求4次(一次原始请求，三次重连请求)，不需要可以设置为0
                .setRetryCount(3);

    }

    private void initAutoSize() {
        //当 App 中出现多进程, 并且您需要适配所有的进程, 就需要在 App 初始化时调用 initCompatMultiProcess()
        //在 Demo 中跳转的三方库中的 DefaultErrorActivity 就是在另外一个进程中, 所以要想适配这个 Activity 就需要调用 initCompatMultiProcess()
        AutoSize.initCompatMultiProcess(this);
        /**
         * 以下是 AndroidAutoSize 可以自定义的参数, {@link AutoSizeConfig} 的每个方法的注释都写的很详细
         * 使用前请一定记得跳进源码，查看方法的注释, 下面的注释只是简单描述!!!
         */
        AutoSizeConfig.getInstance()

                //是否让框架支持自定义 Fragment 的适配参数, 由于这个需求是比较少见的, 所以须要使用者手动开启
                //如果没有这个需求建议不开启
                .setCustomFragment(true)

                //是否屏蔽系统字体大小对 AndroidAutoSize 的影响, 如果为 true, App 内的字体的大小将不会跟随系统设置中字体大小的改变
                //如果为 false, 则会跟随系统设置中字体大小的改变, 默认为 false
                .setExcludeFontScale(true)

                //屏幕适配监听器
                .setOnAdaptListener(new onAdaptListener() {
                    @Override
                    public void onAdaptBefore(Object target, Activity activity) {
                        //使用以下代码, 可支持 Android 的分屏或缩放模式, 但前提是在分屏或缩放模式下当用户改变您 App 的窗口大小时
                        //系统会重绘当前的页面, 经测试在某些机型, 某些情况下系统不会重绘当前页面, ScreenUtils.getScreenSize(activity) 的参数一定要不要传 Application!!!
                        //AutoSizeConfig.getInstance().setScreenWidth(ScreenUtils.getScreenSize(activity)[0]);
                        //AutoSizeConfig.getInstance().setScreenHeight(ScreenUtils.getScreenSize(activity)[1]);
                        // LogcatUtils.d(String.format(Locale.ENGLISH, "%s onAdaptBefore!", target.getClass().getName()));
                    }

                    @Override
                    public void onAdaptAfter(Object target, Activity activity) {
                        //LogcatUtils.d(String.format(Locale.ENGLISH, "%s onAdaptAfter!", target.getClass().getName()));
                    }
                })
                //是否打印 AutoSize 的内部日志, 默认为 true, 如果您不想 AutoSize 打印日志, 则请设置为 false
                .setLog(false);
    }

    /**
     * App Carsh 监听
     */
    private void initAppCarshListener() {

        final Thread.UncaughtExceptionHandler sysExcepHandler = Thread.getDefaultUncaughtExceptionHandler();
        DebugSafeModeUI.init(this);
        Cockroach.install(this, new ExceptionHandler() {
            @Override
            protected void onUncaughtExceptionHappened(Thread thread, Throwable throwable) {
                LogcatUtils.e("AndroidRuntime", "--->onUncaughtExceptionHappened:" + thread + " throwable " + throwable.toString());
                FileWriteUtils.saveCrashLog(getApplicationContext(), throwable);
                OrrorLog.updateLog(FileWriteUtils.upLoadCrashLog(getApplicationContext(), throwable));
                LogcatUtils.e("AndroidRuntime crash 捕获到导致异常崩溃的异常 ");
            }

            @Override
            protected void onBandageExceptionHappened(Throwable throwable) {
                throwable.printStackTrace();//打印警告级别log，该throwable可能是最开始的bug导致的，无需关心
                LogcatUtils.e("AndroidRuntime crash " + "Worked");
            }

            @Override
            protected void onEnterSafeMode() {
                LogcatUtils.e("AndroidRuntime crash 已经进入安全模式 ");
                //Toast.makeText(App.this, getResources().getString(tips), Toast.LENGTH_LONG).show();
                //DebugSafeModeUI.showSafeModeUI();

                /*if (BuildConfig.DEBUG) {
                    Intent intent = new Intent(ReadApplication.this, DebugSafeModeTipActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                }*/
            }

            @Override
            protected void onMayBeBlackScreen(Throwable e) {
                Thread thread = Looper.getMainLooper().getThread();
                LogcatUtils.e("AndroidRuntime", "--->onUncaughtExceptionHappened:" + thread + "<---", e);
                //黑屏时建议直接杀死app
                sysExcepHandler.uncaughtException(thread, new RuntimeException("black screen"));
            }

        });


    }


}
